package com.westline.unicom.util;
/* 
 *北京联通全网有关网上订购和点播接口URL加密算法 
 * 
 *采用3DES加密, ECB模式/使用PKCS7方式填充不足位, 
 *目前给的密钥是192位(24个字节)经过BASE64编码后的可见字符串 
 * 
 *作者：xuchean@gmail.com 
 */

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.Security;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

/* 
 * 配置： 从http://www.bouncycastle.org/latest_releases.html上下载对应JDK的“Provider”, 
 * 如JDK1.6对应bcprov-jdk16-137.jar, 放入CLASSPATH即可. 
 */

public class ThreeDes
{
    
    private static Cipher cipher = null;
    
    // public static final String ALGORITHM = "DESede/ECB/PKCS7Padding";
    public static final String ALGORITHM = "DESede/ECB/PKCS5Padding";
    
    private synchronized static Cipher initCipher(int mode, String key)
    {
        try
        {
            // 添加新安全算法:PKCS7
            Security.addProvider(new BouncyCastleProvider());
            SecretKey desKey = new SecretKeySpec(key.getBytes(), ALGORITHM);
            Cipher tcipher = Cipher.getInstance(ALGORITHM);
            tcipher.init(mode, desKey);
            return tcipher;
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return null;
        }
    }
    
    public synchronized static String encrypt(String src, String charset, String key)
    {
        try
        {
            return URLEncoder.encode(encrypt(src, key), charset);
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return null;
        }
    }
    
    public synchronized static String encrypt(String src, String key)
    {
        
        return byteToString(encrypt(src.getBytes(), key));
    }
    
    public synchronized static byte[] encrypt(byte[] src, String key)
    {
        try
        {
            
            cipher = initCipher(Cipher.ENCRYPT_MODE, key);
            return cipher.doFinal(src);
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return null;
        }
    }
    
    public synchronized static String decrypt(String src, String charset, String key)
    {
        try
        {
            return URLEncoder.encode(decrypt(src, key), charset);
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return null;
        }
    }
    
    public synchronized static String decrypt(String src, String key)
    {
        try
        {
            return new String(decrypt(stringToByte(src), key), "utf-8");
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return null;
        }
    }
    
    public synchronized static byte[] decrypt(byte[] src, String key)
    {
        try
        {
            cipher = initCipher(Cipher.DECRYPT_MODE, key);
            return cipher.doFinal(src);
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return null;
        }
    }
    
    public static void main(String[] args) throws IOException
    {
        
        String s1 = "";
        String s2 = "";
        String s3 = "";
        String key = "204121000329819612345678";
        try
        {
            s3 = new String("sn=1000&mobile=18602533128".getBytes("utf8"), "utf8");
        }
        catch (UnsupportedEncodingException e1)
        {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        byte[] bytes = s3.getBytes();
        byte[] res = encrypt(bytes, key);
        String resStr = byteToString(res);
        byte[] resByte = stringToByte(resStr);
        byte[] raw = decrypt(res, key);
        long start = System.currentTimeMillis();
        long start1;
        long end;
        long end1;
        
        // s3 = "13770623977|高雨峰|01|320102198501020819\r\n"; //
        // UUID.randomUUID().toString();//String.valueOf(Math.random());
        try
        {
            s3 = new String("sn=d2ab65d5-8a84-4606-adea-f9ecf4b954b5&mobile=18652023985".getBytes("utf8"), "utf8");
            // byte[] byt = new String("一一一一一一一".getBytes("gbk"), "gbk").getBytes("gbk");
            String s = new String("一一一一".getBytes("utf8"), "utf8");
            byte[] byt = s.getBytes("utf8");
            String ss = byteToString(byt);
            //s3 = s;
            System.out.println("---" + ss);
        }
        catch (UnsupportedEncodingException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        s1 = ThreeDes.encrypt(s3, key);
        end = System.currentTimeMillis();
        
        start1 = System.currentTimeMillis();
        System.out.println("----" + s1.getBytes().length);
        s2 = ThreeDes.decrypt(s1, key);
        end1 = System.currentTimeMillis();
        String s4="C3D2740B5D54CD0F8A2D1871B026869780747F568449EDAD303D3D2CBB71B416B1CC21F1D1497B2DB162C554A7F6EC5F34050BF14CE42C44D4598CE386269351";
        System.out.println("明文字符串:" + s3);
        System.out.println("密文字符串:" + s1);
        System.out.println("解密字符串:" + s2);
        System.out.println("解密字符串:" + ThreeDes.decrypt(s4, key));
        System.out.println("加密执行时间:" + String.valueOf(end - start) + "毫秒");
        System.out.println("解密执行时间:" + String.valueOf(end1 - start1) + "毫秒");
        System.out.println("==================================================================");
        
    }
    
    public static byte[] padding(byte[] byt)
    {
        return null;
    }
    
    public static byte[] stringToByte(String str)
    {
        byte[] result = new byte[str.length() / 2];
        int j = 0;
        for (int i = 0; i < str.length(); i += 2)
        {
            byte valH = Byte.valueOf(str.charAt(i) + "", 16);
            byte valL = Byte.valueOf(str.charAt(i + 1) + "", 16);
            byte value = (byte)(valH << 4 | valL);
            result[j++] = value;
        }
        return result;
        // String.valueOf(str[i],"16");
    }
    
    public static String byteToString(byte[] byt)
    {
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < byt.length; i++)
        {
            String s = String.format("%x", byt[i]).toUpperCase();
            if (s.length() == 1)
            {
                s = "0" + s;
            }
            stringBuilder.append(s);
        }
        return stringBuilder.toString();
    }
    
}
